/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.springframework.util.xml;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.springframework.util.StringUtils;

/**
 *
 * @author lxz
 */
public class XmlValidationModeDetector {

    public static final int VALIDATION_NONE = 0;
    
    public static final int VALIDATION_AUTO = 1;
    
    public static final int VALIDATION_DTD = 2;
    
    public static final int VALIDATION_XSD = 3;

    private static final String START_COMMENT = "<!--";
    
    private static final String END_COMMENT = "-->";
    
    private static final String DOCTYPE = "DOCTYPE";
    
    private boolean inComment;
    /**
     * 判断xml文件时引用dtd 还是 schema
     * @param inputStream
     * @return
     * @throws IOException
     */
    public int detectValidationMode(InputStream inputStream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        boolean isDtdValidated = false;
        String content;
        while ((content = reader.readLine()) != null) {
            content = consumeCommentTokens(content);
            //inComment主要用来控制多行注释
            if (this.inComment || !StringUtils.hasText(content)) {
                continue;
            }
            if (hasDoctype(content)) {
                isDtdValidated = true;
                break;
            }
            if (hasOpeningTag(content)) {
                break;
            }
        }
        return isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD;
    }
    
    /**
     * 检查字符串'<'后面是否紧跟着字符
     * @param content
     * @return
     */
    private boolean hasOpeningTag(String content) {
        if (this.inComment) {
            return false;
        }
        int index = content.indexOf("<");
        return index > -1 && content.length() > index && Character.isLetter(content.charAt(index + 1));
    }

    /**
     * 检查字符串是否含有 DOCTYPE
     * @param content
     * @return
     */
    private boolean hasDoctype(String content) {
        return content.indexOf(DOCTYPE) > -1;
    }
    /**
     * 判断字符串时候还有 '<!--', '-- >'
     * if 含有'<!--' and '-- >' 返回 ""
     * if 含有'<!--' or '-- >' 返回 null
     * else 返回原字符串
     * @param line
     * @return
     */
    private String consumeCommentTokens(String line) {
        if (line.indexOf(START_COMMENT) == -1 && line.indexOf(END_COMMENT) == -1) {
            return line;
        }
        while ((line = consume(line)) != null) {
            if (!this.inComment && !line.trim().startsWith(START_COMMENT)) {
                return line;
            }
        }
        return line;
    }

    private String consume(String line) {
        int index = this.inComment ? endComment(line) : startComment(line);
        return index == -1 ? null : line.substring(index);
    }
    
    /**
     * if '<!--' 存在  返回 '<!--'所在位置 + '<!--'的长度
     * else -1
     * @param line
     * @return
     */
    private int startComment(String line) {
        return commentToken(line, START_COMMENT, true);
    }
    
    /**
     * if '-->' 存在  返回 '-->'所在位置 + '-->'的长度
     * else -1
     * @param line
     * @return
     */
    private int endComment(String line) {
        return commentToken(line, END_COMMENT, false);
    }
    
    private int commentToken(String line, String token, boolean inCommentIfPresent) {
        int index = line.indexOf(token);
        if (index > -1) {
            this.inComment = inCommentIfPresent;
        }
        return (index == -1) ? index : index + token.length();
    }
    
    public static void main(String[] args) {
        String line = "<!-- sadfasdfsdafsdf -->";
        XmlValidationModeDetector validationModeDetector = new XmlValidationModeDetector();
        String result = validationModeDetector.consumeCommentTokens(line);
        System.out.println(result);
    }
}
